﻿using GN.Pay.TradeChannel.DefaultImpl;
using GN.Pay.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace GN.Pay.TradeChannel.UnionPay.Response
{
    [Serializable]
    public class QueryResponse : AResponse
    {
        /// <summary>
        /// 查询响应
        /// </summary>
        private readonly ITradeChannel channel;
        private readonly UnionPayConfigure config;
        private IDictionary<string, string> xmlDic;
        private readonly TradeOrderQueryResult _result;
        public QueryResponse(string responseString,
            ITradeChannel channel,
            UnionPayConfigure config)
        {
            if (responseString != null)
            {
                this.ResponseString = responseString.Trim();
            }
            else
            {
                this.ResponseString = responseString;
            }
            this.channel = channel;
            this.config = config;

            try
            {
                xmlDic = UrlDic(responseString);
            }
            catch
            {
                throw channel.ThrowInterfaceException(Format_ErrorMessage);
            }
            _result = QueryTesult();
        }

        private static string Format_ErrorMessage = "响应结果格式不正确，没有该订单号的订单信息。";

        /// <summary>
        /// 签名验证
        /// </summary>
        /// <returns></returns>
        public bool SignVeryfy()
        {
            string sign;
            if (!this.xmlDic.TryGetValue(sign_Key, out sign) || string.IsNullOrWhiteSpace(sign))
            {
                return false;
            }
            this.xmlDic.Remove(sign_Key);
            if (this.xmlDic.Count == 0)
            {
                return false;
            }
            SignDictionary sortDic = new SignDictionary(this.xmlDic);
            string content = sortDic.UrlLinkString();
            return SecurityUtils.SignVerify(config.ConfigureInfo, sign, content);
        }


        protected DateTime FormatTime(string time, string format)
        {
            if (string.IsNullOrWhiteSpace(time))
            {
                return DateTime.Now;
            }
            return DateTimeUtils.GetDateTimeFormat(time, format);
        }

        private TradeOrderQueryResult QueryTesult()
        {
            if (string.IsNullOrWhiteSpace(this.ResponseString))
            {
                this.channel.ThrowInterfaceException(Format_ErrorMessage);
            }
            string is_success;
            if (!xmlDic.TryGetValue("respCode", out is_success) || is_success == null)
            {
                throw this.channel.ThrowInterfaceException(Format_ErrorMessage);
            }
            if (is_success.ToString().Equals("00", StringComparison.InvariantCultureIgnoreCase))
            {
                string _merId, _txnTime, _orderId, _queryId, _traceNo, _traceTime, _settleAmt, _txnAmt, _respCode, _resMsg;
                xmlDic.TryGetValue("queryId", out _queryId);
                if (string.IsNullOrWhiteSpace(_queryId))
                {
                    return null;
                }
                xmlDic.TryGetValue("merId", out _merId);
                xmlDic.TryGetValue("txnTime", out _txnTime);
                xmlDic.TryGetValue("orderId", out _orderId);
                xmlDic.TryGetValue("traceNo", out _traceNo);
                xmlDic.TryGetValue("traceTime", out _traceTime);
                xmlDic.TryGetValue("settleAmt", out _settleAmt);
                xmlDic.TryGetValue("txnAmt", out _txnAmt);
                xmlDic.TryGetValue("respCode", out _respCode);
                xmlDic.TryGetValue("respMsg", out _resMsg);
                this.merId = _merId;
                this.txnTime = FormatTime(_txnTime, "yyyyMMddHHmmss");
                this.orderId = _orderId;
                this.queryId = _queryId;
                this.traceNo = _traceNo;
                this.traceTime = FormatTime(_traceTime, "MMddHHmmss");
                this.settleAmt = Convert.ToInt32(_settleAmt) / 100M;
                this.txnAmt = Convert.ToInt32(_txnAmt) / 100M;
                this.respCode = _respCode;
                this.respMsg = _resMsg;
                return  new TradeOrderQueryResult(this.channel)
                {
                    TradeNo = this.queryId,
                    Body = "",
                    OrderNo = this.orderId,
                    OrderMoney = this.txnAmt,
                    PayTime = this.txnTime,
                    PayFee = 0m,
                };
            }
            else
            {
                return null;
            }
        }


        /// <summary>
        /// 商户代码
        /// </summary>
        public string merId { get; set; }


        /// <summary>
        /// 订单发送时间
        /// </summary>
        public DateTime txnTime { get; set; }

        /// <summary>
        /// 订单号
        /// </summary>
        public string orderId { get; set; }


        /// <summary>
        /// 查询流水号
        /// </summary>
        public string queryId { get; set; }


        /// <summary>
        /// 跟踪号
        /// </summary>
        public string traceNo { get; set; }

        public DateTime? traceTime { get; set; }

        /// <summary>
        /// 清算金额
        /// </summary>
        public decimal settleAmt { get; set; }

        /// <summary>
        /// 交易金额
        /// </summary>
        public decimal txnAmt { get; set; }

        /// <summary>
        /// 应答码
        /// </summary>
        public string respCode { get; set; }
        /// <summary>
        /// 应答消息
        /// </summary>
        /// 

        ///支付方式
        public string payType { get; set; }
        public string respMsg { get; set; }
        /// <summary>
        /// 获取响应字符
        /// </summary>
        public string ResponseString { get; private set; }


        /// <summary>
        /// 获取错误代码
        /// </summary>
        public string ErrorCode { get; private set; }

        /// <summary>
        /// 是否成功
        /// </summary>
        public bool IsSuccess()
        {
            return "00".Equals(this.respCode);
        }

        /// <summary>
        /// 转为结果
        /// </summary>      
        /// <returns></returns>
        public ITradeOrderQueryResult ToResult()
        {
            var msg = "";
            if (!this.IsSuccess())
            {
                msg = this.ErrorCode;
            }
            return _result;
        }
    }
}

